/* GUI CONVERTED from mcexrmt.p (converter v1.75) Sun Aug 13 17:03:46 2000 */
/* mcexrmt.p - EXCHANGE RATE MAINTENANCE                                */
/* Copyright 1986-2000 QAD Inc., Carpinteria, CA, USA.                  */
/* All rights reserved worldwide.  This is an unpublished work.         */
/*V8:ConvertMode=Maintenance                                            */
/*V8:RunMode=Character,Windows */
/* REVISION: 8.6E        CREATED: 05/21/98   BY: *L018*  Russ Witt      */
/* REVISION: 8.6E       MODIFIED: 07/22/98   BY: *L04F*  Russ Witt      */
/* REVISION: 8.6E       MODIFIED: 08/24/98   BY: *L06X*  Russ Witt      */
/* REVISION: 8.6E       MODIFIED: 01/05/99   BY: *L09G*  Robin McCarthy */
/* REVISION: 9.0        MODIFIED: 03/10/99   BY: *M0B8* Hemanth Ebenezer */
/* REVISION: 9.0        MODIFIED: 03/13/99   BY: *M0BD* Alfred Tan       */
/* REVISION: 9.0        MODIFIED: 12/10/99   BY: *M0GM* Atul Dhatrak     */
/* REVISION: 9.1      LAST MODIFIED: 03/24/00 BY: *N08T* Annasaheb Rahane */
/* REVISION: 9.1      LAST MODIFIED: 05/15/00 BY: *N0BC* Annasaheb Rahane */
/* REVISION: 9.1      LAST MODIFIED: 08/13/00 BY: *N0KR* myb              */

/************************************************************************/
/*!
      mcexrmt.p EXCHANGE RATE MAINTENANCE - FOR DEFINING THE CURRENCY
                EXCHANGE RATES BETWEEN 2 CURRENCIES.

/*L09G    REDESIGNED PROGRAM --- OLD CODE FOLLOWING VARIABLE DEFINITIONS
          HAS BEEN MOVED TO BOTTOM OF THIS FILE TO IMPROVE READABILITY.  */
*/
/**********************************************************************/

          /* ********** Begin Translatable Strings Definitions ********* */

/*N0BC*   &SCOPED-DEFINE mcexrmt_p_1 "Units"                             */
          /* MaxLen: 11 Comment: USED TO DESCRIBE ONE COMPONENT OF       */
          /*                     CURRENCY EXCHANGE RATE, AS USD UNITS    */
          /*                     OR FFR UNITS.                           */

          /* ********** End Translatable Strings Definitions *********   */

          /* DISPLAY TITLE */
          {mfdtitle.i "b+ "}

/*L09G    CHANGED MOST like mfc_logical REFERENCES BELOW TO as logical */
          define variable del-yn                like mfc_logical     no-undo.
          define variable chg-ok                like mfc_logical     no-undo.
          define variable is-EMU-exch-rate      as logical           no-undo.
          define variable next-start            like exr_start_date  no-undo.
          define variable error-number          as integer           no-undo.
/*L09G*/  define variable error-parm1           as character         no-undo.
/*L09G*/  define variable error-end-date        as date              no-undo.
          define variable recnum                as recid extent 10   no-undo.
          define variable i                     as integer           no-undo.
          define variable curr1                 like exr_curr1       no-undo.
          define variable curr2                 like exr_curr2       no-undo.
          define variable curr1-desc            like cu_desc         no-undo.
          define variable curr2-desc            like cu_desc         no-undo.
          define variable curr1-is-union        as logical           no-undo.
/*L09G*/  define variable curr1-is-union-start  as logical           no-undo.
/*L09G*/  define variable curr1-is-union-end    as logical           no-undo.
/*L09G*/  define variable curr1-is-union-ever   as logical           no-undo.
          define variable curr2-is-union        as logical           no-undo.
/*L09G*/  define variable curr2-is-union-start  as logical           no-undo.
/*L09G*/  define variable curr2-is-union-end    as logical           no-undo.
/*L09G*/  define variable curr2-is-union-ever   as logical           no-undo.
          define variable curr1-is-member       as logical           no-undo.
/*L09G*/  define variable curr1-is-member-start as logical           no-undo.
/*L09G*/  define variable curr1-is-member-end   as logical           no-undo.
/*L09G*/  define variable curr1-is-member-ever  as logical           no-undo.
          define variable curr2-is-member       as logical           no-undo.
/*L09G*/  define variable curr2-is-member-start as logical           no-undo.
/*L09G*/  define variable curr2-is-member-end   as logical           no-undo.
/*L09G*/  define variable curr2-is-member-ever  as logical           no-undo.
          define variable curr1-is-base         as logical           no-undo.
          define variable curr2-is-base         as logical           no-undo.
/*L09G*/  define variable base-is-member        as logical           no-undo.
/*L09G*/  define variable base-is-member-ever   as logical           no-undo.
/*L09G*/  define variable base-is-union         as logical           no-undo.
/*L09G*/  define variable base-is-union-ever    as logical           no-undo.
/*L09G*/  define variable base-is-neither       as logical           no-undo.
          define variable union-curr            like mu_union_curr   no-undo.
/*N0BC*   define variable rate-amt1             like exr_rate        no-undo. */
/*N0BC*/  define variable rate-amt1             like exr_rate        no-undo
/*N0BC*/  label "XXXXXXXXXXXXXX". /*ENLARGE SIZE OF LABEL TO 14 CHARACTERS*/
/*N0BC*   define variable rate-amt2             like exr_rate2       no-undo. */
/*N0BC*/  define variable rate-amt2             like exr_rate2       no-undo
/*N0BC*/  label "XXXXXXXXXXXXXX". /*ENLARGE SIZE OF LABEL TO 14 CHARACTERS*/
          define variable save-end-date         like exr_end_date    no-undo.
          define variable save-rate-amt1        like exr_rate        no-undo.
          define variable save-rate-amt2        like exr_rate2       no-undo.
/*N0BC*/  define variable c-rate-label          as character         no-undo.

          define buffer exrrate         for exr_rate.

          define query q1 for exr_rate scrolling.

/*L09G*/  define temp-table currency-pair no-undo
             field currency1 like exr_curr1
             field currency2 like exr_curr2
             index curr-pair currency1 ascending
                             currency2 ascending.

/*L09G*/  define temp-table currencies no-undo
             field currency like exr_curr1
             index curr     currency ascending.

          /* CREATE VARIABLES FOR TEMPORARY FILES USED IN THE AUDIT TRAIL */
          {gpaud.i &uniq_num1 = 1
                   &uniq_num2 = 2
                   &db_file   = exr_rate
                   &db_field  = exr_curr1}

          /* DISPLAY SELECTION FORM */
          
/*GUI preprocessor Frame A define */
&SCOPED-DEFINE PP_FRAME_NAME A

FORM /*GUI*/ 
             
 RECT-FRAME       AT ROW 1 COLUMN 1.25
 RECT-FRAME-LABEL AT ROW 1 COLUMN 3 NO-LABEL VIEW-AS TEXT SIZE-PIXELS 1 BY 1
 SKIP(.1)  /*GUI*/
curr1            colon 10 space(2)
             curr1-desc       no-label
             curr2            space(2)
             curr2-desc       no-label
           SKIP(.4)  /*GUI*/
with frame a side-labels width 80 NO-BOX THREE-D /*GUI*/.

 DEFINE VARIABLE F-a-title AS CHARACTER INITIAL "".
 RECT-FRAME-LABEL:SCREEN-VALUE in frame a = F-a-title.
 RECT-FRAME-LABEL:HIDDEN in frame a = yes.
 RECT-FRAME:HEIGHT-PIXELS in frame a =
  FRAME a:HEIGHT-PIXELS - RECT-FRAME:Y in frame a - 2.
 RECT-FRAME:WIDTH-CHARS IN FRAME a = FRAME a:WIDTH-CHARS - .5.  /*GUI*/

/*GUI preprocessor Frame A undefine */
&UNDEFINE PP_FRAME_NAME



          /* SET EXTERNAL LABELS */
          setFrameLabels(frame a:handle).

          /* RATE INPUT FORM */
          FORM /*GUI*/ 
             exr_start_date
             exr_end_date
             rate-amt1
             rate-amt2
          with frame b attr-space down width 80 THREE-D /*GUI*/.


          /* SET EXTERNAL LABELS */
          setFrameLabels(frame b:handle).

          /* DISPLAY */
          mainloop: repeat on endkey undo, leave mainloop:
/*GUI*/ if global-beam-me-up then undo, leave.


            /* BUILD TEMP TABLES USED TO DISPLAY CURRENCY PAIRS FOR mfnp.i */
            for each exr_rate where exr_curr1 > "" no-lock:
               if not can-find (first currencies where currency = exr_curr1)
               then do:
                  create currencies.
                  currency = exr_curr1.
               end.

               if not can-find (first currencies where currency = exr_curr2)
               then do:
                  create currencies.
                  currency = exr_curr2.
               end.

               if can-find (first currency-pair where currency1 = exr_curr1
               and currency2 = exr_curr2) then next.

               if can-find (first currency-pair where currency1 = exr_curr2
               and currency2 = exr_curr1) then next.

               create currency-pair.
               if can-find (first currency-pair where currency2 = exr_curr1)
               then
                  assign currency1 = exr_curr2
                         currency2 = exr_curr1.
               else
                  assign currency1 = exr_curr1
                         currency2 = exr_curr2.
            end.

            set curr1 with frame a editing:
               /* FIND NEXT/PREVIOUS RECORD */
               {mfnp.i currencies curr1 currency curr1 currency curr}

               if recno <> ? then do with frame a:
                  for first cu_mstr fields (cu_curr cu_desc) no-lock
                  where cu_curr = currency: end.

                  assign curr1 = cu_curr
                         curr2 = ""
                         curr2-desc = ""
                         curr1-desc = cu_desc.

                  display  curr1
                           curr2
                           curr2-desc
                           curr1-desc.
               end.  /* IF RECNO <> ?... */
            end.
/*GUI*/ if global-beam-me-up then undo, leave.
  /* SET FOR CURR1... */

            /* CURR1 MUST BE VALID CURRENCY        */
            {gprunp.i "mcpl" "p" "mc-chk-valid-curr"
                      "(input  curr1,
                        output error-number)"}

            if error-number = 3088 then do:
               {mfmsg.i error-number 3}
               /* INVALID/INACTIVE CURRENCY */
               next-prompt curr1 with frame a.
               undo mainloop, retry mainloop.
            end.  /* ERROR-NUMBER = 3088... */

            /* IF CURR1 IS INACTIVE, ISSUE WARNING  */
            if error-number = 2659 then do:
               chg-ok = no.
               {mfmsg01.i 2668 2 chg-ok}
               /* WARNING: THIS CURRENCY IS INACTIVE. CONTINUE?   */

               if not chg-ok then do:
                  next-prompt curr1 with frame a.
                  undo mainloop, retry mainloop.
               end.
            end.  /* ERROR-NUMBER = 2659... */

            /* DISPLAY CURR1 DESCRIPTION    */
            for first cu_mstr fields (cu_curr cu_desc) no-lock
            where cu_curr = curr1:
               display cu_desc @ curr1-desc with frame a.
            end.

            setcurr2: do on error undo, retry:
/*GUI*/ if global-beam-me-up then undo, leave.

               set curr2 with frame a editing:
                  /* FIND NEXT/PREVIOUS RECORD */
                  {mfnp06.i currency-pair
                            curr-pair
                            "currency1 = input curr1
                             or currency2 = input curr1"
                            currency1
                            "' '"
                            currency2
                            "' '"}

                  if recno <> ? then do with frame a:
                     if currency1 = curr1 then
                        for first cu_mstr fields (cu_curr cu_desc) no-lock
                        where cu_curr = currency2: end.
                     else
                        for first cu_mstr fields (cu_curr cu_desc) no-lock
                        where cu_curr = currency1: end.

                     assign curr2 = cu_curr
                            curr2-desc = cu_desc.

                     display  curr2
                              curr2-desc.
                  end.
/*GUI*/ if global-beam-me-up then undo, leave.
  /* IF RECNO <> ?... */
               end.  /* SET FOR CURR2... */

               /* CURR2 MUST BE VALID AND ACTIVE CURRENCY      */
               {gprunp.i "mcpl" "p" "mc-chk-valid-curr"
                         "(input  curr2,
                           output error-number)"}

               if error-number = 3088 then do:
                  {mfmsg.i error-number 3}
                  /* INVALID/INACTIVE CURRENCY */
                  next-prompt curr2 with frame a.
                  undo setcurr2, retry.
               end.  /* IF ERROR-NUMBER = 3088... */

               /* IF CURR2 IS INACTIVE, ISSUE WARNING  */
               if error-number = 2659 then do:
                  chg-ok = no.
                  {mfmsg01.i 2668 2 chg-ok}
                  /* WARNING: THIS CURRENCY IS INACTIVE. CONTINUE?   */

                  if not chg-ok then do:
                     next-prompt curr2 with frame a.
                     undo setcurr2, retry.
                  end.
               end.  /* IF ERROR-NUMBER = 2659... */

               /* DISPLAY CURR2 DESCRIPTION    */
               for first cu_mstr fields (cu_curr cu_desc) no-lock
               where cu_curr = curr2:
                  display cu_desc @ curr2-desc with frame a.
               end.

               /* CURR1 CANNOT BE SAME AS CURR2    */
               if curr1 = curr2  then do:
                  {mfmsg.i 2670 3}
                  /* BOTH CURRENCIES CANNOT BE THE SAME CURRENCY CODE */
                  next-prompt curr2 with frame a.
                  undo setcurr2, retry.
               end.  /* ERROR-NUMBER <> 0... */
            end.  /* setcurr2 */

            /* USE QUERY TO RETRIEVE RECORDS TO BE DISPLAYED */
            /* QUERIES NEED TO BE WRAPPED IN DO STATEMENT FOR GUI */
            do:
               open query q1 for each exr_rate no-lock where
                    (exr_curr1 = curr1 and exr_curr2 = curr2)
                    or (exr_curr2 = curr1 and exr_curr1 = curr2)
                    by exr_start_date.
            end.

            assign i = 11
                   recnum = 0.

            get last q1.

            do while available exr_rate:
               assign i = i - 1
                      recnum[i] = recid(exr_rate).
               if i = 1 then leave.
               get prev q1.
            end.   /* DO WHILE AVAILABLE EXR_RATE... */

            if i <> 11 then do:
               do i = 1 to 10:
                  if recnum[i] = 0 then next.
                  reposition q1 to recid recnum[i].
                  get next q1.
                  assign rate-amt1 = (if curr1 = exr_curr1 then exr_rate
                                                           else exr_rate2)
                         rate-amt2 = (if curr1 = exr_curr1 then exr_rate2
                                                      else exr_rate).
                  display exr_start_date exr_end_date rate-amt1 rate-amt2
                          with down frame b.
                  down 1 with frame b.
               end.   /* DO I = 1 TO 10...   */
               next-start = exr_end_date + 1.
            end.     /* IF I <> 11... */
            else next-start = today.

            loopb:  repeat:
/*GUI*/ if global-beam-me-up then undo, leave.

             innerloop: repeat with frame b width 80
                         on endkey undo, leave loopb:
/*GUI*/ if global-beam-me-up then undo, leave.


               /* HEADING IN FRAME IS CONCATENATION OF CAPITALIZED CURRENCY */
               /* CODE AND "UNITS"                                          */
/*N0BC* --------------- BEGIN COMMENT CODE -------------------------------- *
 *             assign
 *                rate-amt1:label = caps(string(curr1)) + " " + {&mcexrmt_p_1}
 *                rate-amt2:label = "  " + caps(string(curr2)) +  " " +
 *                                  {&mcexrmt_p_1}.
 *N0BC* --------------- END   COMMENT CODE -------------------------------- */
/*N0BC* --------------- BEGIN ADD CODE ------------------------------------ */
           c-rate-label    = caps(string(curr1)) + " " +
                 getTermLabel("UNITS",10).
               rate-amt1:label = fill(" ", 14 - length(c-rate-label,"raw")) +
                 c-rate-label.
               c-rate-label    = caps(string(curr2)) +  " " +
                 getTermLabel("UNITS",10).
               rate-amt2:label = fill(" ", 14 - length(c-rate-label,"raw")) +
                 c-rate-label.
/*N0BC* --------------- END   ADD CODE ------------------------------------ */

               display next-start @ exr_start_date.

               dateframe: do on endkey undo loopb, leave
                             on error undo, retry:
/*GUI*/ if global-beam-me-up then undo, leave.


                  prompt-for exr_start_date editing:
                      ststatus = stline[1].
                      status input ststatus.
                      readkey.
                      hide message no-pause.

                      /* FIND NEXT/PREV RECORD */
                      /* NOTE: STANDARD mfnp.i NOT USED BECAUSE IT CANNOT     */
                      /* CHECK CONTENTS OF 2 FIELDS (exr_curr1 and exr_curr2) */
                      /* FOR MATCHING DATA WHEN SCROLLING.                    */
                      if lastkey = keycode("F10")
                      or keyfunction(lastkey) = "CURSOR-DOWN"
                      then do:
                         if recno = ? then get first q1.
                         else get next q1.
                         if not available exr_rate then do:
                            {mfmsg.i 20 2}  /* END OF FILE */
                            if recno = ? then get last q1.
                            else if recno <> ? then do:
                               reposition q1 to recid recno.
                               get next q1.
                            end.
                            input clear.
                         end.     /* IF NOT AVAILABLE EXR_RATE...     */
                         recno = recid(exr_rate).
                      end.   /* LASTKEY = KEYCODE("F10")... */

                      /* FIND PREVIOUS RECORD  */
                      else if lastkey = keycode("F9")
                            or keyfunction(lastkey) = "CURSOR-UP"
                      then do:
                         if recno = ? then get last q1.
                         else get prev q1.
                         if not available exr_rate then do:
                            {mfmsg.i 21 2}  /* BEGINNING OF FILE */
                            if recno = ? then get first q1.
                            else if recno <> ? then do:
                               reposition q1 to recid recno.
                               get next q1.
                            end.
                            input clear.
                         end.
                         recno = recid(exr_rate).
                      end.   /* LASTKEY = KEYCODE("F9")... */

                      /* INPUT PROMPT FIELD */
                      else do:
                         recno = ?.
                         if keyfunction(lastkey) = "end-error" then do:
                            ststatus = stline[3].
                            status input ststatus.
                         end.  /* LASTKEY = "END-ERROR"... */
                         apply lastkey.
                      end.   /* ELSE DO...  */

                      if available exr_rate then do:
                         if curr1 = exr_curr1 then
                            assign  rate-amt1 = exr_rate
                                    rate-amt2 = exr_rate2.
                         else assign rate-amt1 = exr_rate2
                                     rate-amt2 = exr_rate.

                         if recno <> ? then display exr_start_date
                                                    exr_end_date
                                                    rate-amt1
                                                    rate-amt2.
                      end.   /* IF AVAILABLE EXR_RATE... */
                  end.    /* PROMPT-FOR EXR_START_DATE EDITING... */

                  /* DETERMINES WHETHER CURR1 AND CURR2 ARE EVER THE   */
                  /* UNION CURRENCY OR EVER A MEMBER CURRENCY.         */
                  run ip-chk-currs-ever.

                  /* VALIDATE START DATE ENTERED */
                  run ip-edit-start-date
                         (input  input exr_start_date).

                  if error-number <> 0 then do:
                     {mfmsg03.i error-number 3 error-parm1 """" """"}
                     next-prompt exr_start_date with frame b.
                     undo, retry.
                  end.  /* IF ERROR-NUMBER <> 0...  */

                  save-end-date = ?.

                  setb: do on error undo, retry:
/*GUI*/ if global-beam-me-up then undo, leave.

                     ststatus = stline[3].
                     status input ststatus.

                     /* FIND EXISTING RECORD TO MODIFY                        */

/*M0GM*/             /* ADDED ADDITIONAL CONDITION TO CHECK ENTERED END DATE  */
/*M0GM*/             /* TO AVOID ENTERING EXCHANGE RATE DETAIL LINE WITH SAME */
/*M0GM*/             /* START DATE BUT DIFFERENT END DATE AS EXISTING DETAIL  */
/*M0GM*/             /* LINE TO BE TREATED AS MODIFICATION TO THE LINE        */

                     for first exr_rate exclusive-lock where
                        ((exr_curr1 = curr1 and exr_curr2 = curr2)
                        or (exr_curr1 = curr2 and exr_curr2 = curr1))
                        and exr_ratetype   = ""
/*M0GM**                and exr_start_date = input exr_start_date: end.       */
/*M0GM*/                and exr_start_date = input exr_start_date
/*/*M0GM*/                and exr_end_date   = input exr_end_date fdn*/ :
/*M0GM*/             end.
/*GUI*/ if global-beam-me-up then undo, leave.

                    /*fdn*/
                    IF AVAILABLE exr_rate THEN
                        DISPLAY exr_end_date.
                    ELSE
                        DISPLAY DATE(MONTH((INPUT exr_start_date) + 365), 1, YEAR((INPUT exr_start_date) + 365)) - 1 @ exr_end_date.

                     prompt-for exr_end_date.


                     if available exr_rate then do:
                        {mfmsg.i 10 1}    /*MODIFYING EXISTING RECORD*/
                        assign save-end-date  = exr_end_date
                               save-rate-amt1 = (if curr1 = exr_curr1
                                                then exr_rate else exr_rate2)
                               save-rate-amt2 = (if curr1 = exr_curr1
                                                then exr_rate2 else exr_rate).

                        if input exr_end_date <> save-end-date then do:
                           /* VALIDATE END DATE ENTERED */
                           run ip-edit-end-date
                               (input  input exr_start_date,
                                input  input exr_end_date).

                           if error-number = 0 then do:
                              /* VALIDATE DATE RANGE */
                              run ip-chk-date-range
                                  (input  input exr_start_date,
                                   input  input exr_end_date).
                           end.

                           if error-number <> 0 then do:
                              {mfmsg03.i error-number 3 error-parm1 """" """"}
                              next-prompt exr_end_date with frame b.
                              undo setb, retry.
                           end.
                        end.   /* IF INPUT EXR_END_DATE <> SAVE-END-DATE */

                        assign exr_end_date.

                     end.   /* IF AVAILABLE exr_rate  */
                     else do:
                        /* VALIDATE END DATE ENTERED */
                        run ip-edit-end-date
                            (input  input exr_start_date,
                             input  input exr_end_date).

                        if error-number = 0 then do:
                           /* VALIDATE DATE RANGE */
                           run ip-chk-date-range
                               (input  input exr_start_date,
                                input  input exr_end_date).
                        end.

                        if error-number <> 0 then do:
                           {mfmsg03.i error-number 3 error-parm1 """" """"}
                           next-prompt exr_end_date with frame b.
                           undo setb, retry.
                        end.  /* IF ERROR-NUMBER <> 0...  */

                        /* ADD RECORD */
                        {mfmsg.i 1 1} /* ADDING NEW RECORD */

                        do for exrrate:
                           find first exrrate where
                           (exr_curr1 = curr1 and exr_curr2 = curr2) or
                           (exr_curr2 = curr1 and exr_curr1 = curr2)
                           no-lock no-error.

                           create exr_rate.

                           if available exrrate then
                              assign
                                 exr_rate.exr_curr1 =
                                    (if curr1 = exrrate.exr_curr1 then curr1
                                     else curr2)
                                 exr_rate.exr_curr2 =
                                    (if curr2 = exrrate.exr_curr2 then curr2
                                     else curr1)
                                 exr_rate.exr_ratetype   = ""
                                 exr_rate.exr_start_date =
                                    input exr_rate.exr_start_date
                                 exr_rate.exr_end_date   =
                                    input exr_rate.exr_end_date.
                           else
                              assign
                                 exr_rate.exr_curr1 = curr1
                                 exr_rate.exr_curr2 = curr2
                                 exr_rate.exr_ratetype   = ""
                                 exr_rate.exr_start_date =
                                    input exr_rate.exr_start_date
                                 exr_rate.exr_end_date   =
                                    input exr_rate.exr_end_date.
                        end.   /* DO FOR EXRRATE */

                        if recid(exr_rate) = -1 then .
                     end.   /* ELSE DO... */

                     /* TIMESTAMP RECORD */
                     assign exr_mod_date   = today
                            exr_mod_userid = global_userid
                            recno = recid(exr_rate).

                     /* AUDIT TRAIL RECORDS WILL BE CREATED    */
                     /* TO CAPTURE THE BEFORE IMAGE            */
                     run ip-aud1.

                     ststatus = stline[2].
                     status input ststatus.
                     assign del-yn = no
                            rate-amt1 = (if curr1 = exr_curr1
                                        then exr_rate else exr_rate2)

                            rate-amt2 = (if curr1 = exr_curr1
                                        then exr_rate2 else exr_rate)
                            is-EMU-exch-rate = no.

                     /* CHECK IF CURR1 IS A UNION CURRENCY            */
                     /* AND IF CURR2 IS A MEMBER OF THAT UNION        */
                     /* IF SO, SET VALUE TO 1.0 AND INHIBIT INPUT     */
                     if curr1-is-union and curr2-is-member then
                        assign rate-amt1 = 1.0
                               is-EMU-exch-rate = yes.

                     /* CHECK IF CURR2 IS A UNION CURRENCY            */
                     /* AND IF CURR1 IS A MEMBER OF THAT UNION        */
                     /* IF SO, SET VALUE TO 1.0 AND INHIBIT INPUT     */
                     if curr2-is-union and curr1-is-member then
                        assign rate-amt2 = 1.0
                               is-EMU-exch-rate = yes.

                     display exr_end_date
                             rate-amt1
                             rate-amt2.

                     setrates: do on error undo, retry:
/*GUI*/ if global-beam-me-up then undo, leave.

                        /* PROHIBIT INPUT IF UNION CURR AND MEMBER CURR */
                        prompt-for rate-amt1 when (not curr1-is-union
                                                   or not curr2-is-member)
                                   rate-amt2 when (not curr2-is-union
                                                   or not curr1-is-member)
                        go-on (F5 CTRL-D).

                        /* DO NOT ALLOW UNKNOWN VALUE ENTERED */
                        if input rate-amt1 = ? then do:
                           {mfmsg.i 1235 3}   /* UNKNOWN VALUE NOT ALLOWED */
                           next-prompt rate-amt1 with frame b.
                           undo setrates, retry setrates.
                        end.

                        if input rate-amt2 = ? then do:
                           {mfmsg.i 1235 3}   /* UNKNOWN VALUE NOT ALLOWED */
                           next-prompt rate-amt2 with frame b.
                           undo setrates, retry setrates.
                        end.

                        assign rate-amt1
                               rate-amt2.

                        if lastkey = keycode("F5") or
                           lastkey = keycode("CTRL-D")
                        then do:
                           del-yn = yes.
                           {mfmsg01.i 11 1 del-yn}   /*CONFIRM DELETE*/
                        end.

                        if del-yn then do:
                           /* ISSUE WARNING MESSAGE IF END DATE  */
                           /* < OR = TODAY                       */
                           if exr_end_date <= today then do:
                              del-yn = no.
                              {mfmsg01.i 2660 2 del-yn}
                              /* WARNING: DELETION COULD AFFECT      */
                              /* EXISTING TRANSACTIONS. CONTINUE?   */
                           end.    /* IF EXR_END_DATE <= TODAY.. */

                           if del-yn then do:
                              delete exr_rate.
                              clear frame b.
                              assign recno = ?
                                     del-yn = no.
                              leave innerloop.
                           end.    /* IF DEL-YN... */
                        end.    /* IF DEL-YN... */

                        /* VALIDATE THE RATES THAT HAVE BEEN ENTERED */
                        /* ZERO OR NEGATIVE RATES ARE NOT ALLOWED */
                        if rate-amt1 <= 0 or rate-amt2 <= 0 then do:
                           {mfmsg.i 3163 3}
                           /* EXCHANGE RATE MUST BE > THAN ZERO */
                           if rate-amt1 = 0 then next-prompt rate-amt1.
                           else next-prompt rate-amt2.
                           undo setrates, retry.
                        end.   /* RATE-AMT1 = 0 OR RATE-AMT2 = 0... */

                        assign exr_rate = (if curr1 = exr_curr1
                                          then rate-amt1 else rate-amt2)
                               exr_rate2 = (if curr1 = exr_curr1
                                          then rate-amt2 else rate-amt1).

                        /* ISSUE WARNING MESSAGE IF END DATE  */
                        /* < OR = TODAY AND END DATE OR RATES */
                        /* HAVE CHANGED                       */
                        if (exr_end_date <= today and not new exr_rate and
                           (exr_end_date <> save-end-date or
                            rate-amt1 <> save-rate-amt1 or
                            rate-amt2 <> save-rate-amt2))
                        then do:
                           chg-ok = no.
                           {mfmsg01.i 2237 2 chg-ok}
                           /* WARNING: THIS CHANGE COULD AFFECT   */
                           /* EXISTING TRANSACTIONS. CONTINUE?    */
                           if not chg-ok then undo setb, retry.
                        end.    /* IF EXR_END_DATE <= TODAY..     */

                        /* ISSUE WARNING MESSAGE IF THIS IS A     */
                        /* EMU UNION/MEMBER EXCH RATE AND RATES   */
                        /* HAVE CHANGED                           */
                        if (is-EMU-exch-rate and not new exr_rate and
                            (rate-amt1 <> save-rate-amt1 or
                            rate-amt2 <> save-rate-amt2))
                        then do:
                           chg-ok = no.
                           {mfmsg01.i 2669 2 chg-ok}
                           /* WARNING: RATES CHANGED FOR EMU      */
                           /* EXCHANGE RATE. CONTINUE?            */
                           if not chg-ok then undo setb, retry.
                        end.    /* IF IS-EMU-EXCH-RATE..          */

                     end.
/*GUI*/ if global-beam-me-up then undo, leave.
  /* END SETRATES BLOCK */

                  end.
/*GUI*/ if global-beam-me-up then undo, leave.
  /* END SETB BLOCK */

               end.
/*GUI*/ if global-beam-me-up then undo, leave.
  /* END DATEFRAME BLOCK */

               down 1.
               status input.

               leave innerloop.  /* PROCESS COMPLETED NORMALLY */
             end.
/*GUI*/ if global-beam-me-up then undo, leave.
 /* INNERLOOP */

             /* AUDIT TRAIL RECORDS WILL BE CREATED    */
             /* SHOWING ANY CHANGES THAT OCCURED       */
             run ip-aud2.

             /* QUERIES NEED TO BE WRAPPED IN DO STATEMENT FOR GUI */
             do:
                open query q1 for each exr_rate no-lock where
                (exr_curr1 = curr1 and exr_curr2 = curr2)
                or (exr_curr2 = curr1 and exr_curr1 = curr2)
                by exr_start_date.
             end.

             get last q1.

             if available exr_rate then
                assign recno = ?
                next-start = exr_end_date + 1.

            end. /* LOOPB */

            clear frame b all.
            hide frame b.

          end.  /* MAINLOOP */

          /* DELETE TEMPORARY FILES USED FOR AUDIT TRAIL */
          run ip-aud3.

          status input.

          /*----------------------------------------------------------*/

          /* INTERNAL PROCEDURES */

          PROCEDURE ip-aud1:
            /* AUDIT TRAIL RECORDS WILL BE CREATED    */
            /* TO CAPTURE THE BEFORE IMAGE            */
            {gpaud1.i &uniq_num1 = 1
                      &uniq_num2 = 2
                      &db_file   = exr_rate
                      &db_field  = exr_rate.exr_curr1
                      &db_field1 = exr_rate.exr_curr2}
          END PROCEDURE.  /* IP-AUD1 */

          /*----------------------------------------------------------*/

          PROCEDURE ip-aud2:
             /* AUDIT TRAIL RECORDS WILL BE CREATED    */
             /* SHOWING ANY CHANGES THAT OCCURED       */
             {gpaud2.i &uniq_num1 = 1
                       &uniq_num2 = 2
                       &db_file   = exr_rate
                       &db_field  = exr_rate.exr_curr1
                       &db_field1 = exr_rate.exr_curr2}
          END PROCEDURE.  /* IP-AUD2 */

          /*----------------------------------------------------------*/

          PROCEDURE ip-aud3:
             /* DELETE TEMPORARY FILES USED FOR AUDIT TRAIL */
          {gpaud3.i &uniq_num1 = 1
                    &uniq_num2 = 2
                    &db_file   = exr_rate
                    &db_field  = exr_rate.exr_curr1}
          END PROCEDURE.  /* IP-AUD3 */

          /*----------------------------------------------------------*/

          PROCEDURE ip-chk-currs-ever:

             /* DETERMINES WHETHER CURR1 AND CURR2 ARE EVER THE   */
             /* UNION CURRENCY OR EVER A MEMBER CURRENCY.         */

             /* CHECK IF CURR1 IS EVER THE UNION */
             {gprunp.i "mcpl" "p" "mc-chk-union-curr"
                       "(input  curr1,
                         input  ?,
                         output curr1-is-union-ever)"}

             /* CHECK IF CURR2 IS EVER THE UNION */
             {gprunp.i "mcpl" "p" "mc-chk-union-curr"
                       "(input  curr2,
                         input  ?,
                         output curr2-is-union-ever)"}

             /* CHECK IF BASE CURRENCY IS EVER THE UNION */
             {gprunp.i "mcpl" "p" "mc-chk-union-curr"
                       "(input  base_curr,
                         input  ?,
                         output base-is-union-ever)"}

             /* CHECK IF CURR1 IS EVER A MEMBER */
             {gprunp.i "mcpl" "p" "mc-chk-member-curr"
                       "(input  curr1,
                         input  ?,
                         output union-curr,
                         output curr1-is-member-ever)"}

             /* CHECK IF CURR2 IS EVER A MEMBER */
             {gprunp.i "mcpl" "p" "mc-chk-member-curr"
                       "(input  curr2,
                         input  ?,
                         output union-curr,
                         output curr2-is-member-ever)"}

             /* CHECK IF BASE CURRENCY IS EVER A MEMBER */
             {gprunp.i "mcpl" "p" "mc-chk-member-curr"
                       "(input  base_curr,
                         input  ?,
                         output union-curr,
                         output base-is-member-ever)"}

             if not base-is-member-ever and not base-is-union-ever then
                base-is-neither = yes.

          END PROCEDURE.  /* IP-CHK-CURRS-EVER */

          /*----------------------------------------------------------*/

          PROCEDURE ip-chk-currs-this-date:

            /* THIS ROUTINE WILL DETERMINE IF CURRENCIES ARE UNION, MEMBER OR */
            /* BASE CURRENCIES IN EFFECT AS OF THE DATE PASSED TO THE ROUTINE */

            define input parameter i-date     as date no-undo.

            {gprunp.i "mcpl" "p" "mc-chk-union-curr"
                      "(input  curr1,
                        input  i-date,
                        output curr1-is-union)"}

            {gprunp.i "mcpl" "p" "mc-chk-union-curr"
                      "(input  curr2,
                        input  i-date,
                        output curr2-is-union)"}

            {gprunp.i "mcpl" "p" "mc-chk-member-curr"
                      "(input  base_curr,
                        input  i-date,
                        output union-curr,
                        output base-is-member)"}

            {gprunp.i "mcpl" "p" "mc-chk-union-curr"
                      "(input  base_curr,
                        input  i-date,
                        output base-is-union)"}

            {gprunp.i "mcpl" "p" "mc-chk-member-curr"
                      "(input  curr1,
                        input  i-date,
                        output union-curr,
                        output curr1-is-member)"}

            {gprunp.i "mcpl" "p" "mc-chk-member-curr"
                      "(input  curr2,
                        input  i-date,
                        output union-curr,
                        output curr2-is-member)"}

          END PROCEDURE.  /* IP-CHK-CURRS-THIS-DATE */

          /*----------------------------------------------------------*/

          PROCEDURE ip-chk-curr-relations:

             /* VALIDATES RELATIONSHIP BETWEEN CURRENCIES   */
             /* RETURN ERROR NUMBER OF ANY ERROR DETECTED   */
             /* VIA OUTPUT PARAMETERS:                      */
             /*    ERROR-NUMBER   - MESSAGE#                */
             /*    ERROR-PARM1    - MESSAGE PARAMETER #1    */
             /* INPUT PARAMETERS:                           */
             /*    START-DATE or                            */
             /*    END-DATE                                 */

             define input parameter i-date     as date no-undo.

             assign error-number = 0
                    error-parm1 = "".

             /* ONE OF THE CURRENCIES MUST BE THE BASE OR UNION CURRENCY */
             if not curr1-is-base and
             not curr1-is-union and
             not curr2-is-base and
             not curr2-is-union then do:

                /* IF CURR1 IS A UNION CURRENCY AND CURR2 IS A MEMBER   */
                /* CURRENCY AT ANY TIME THEN ISSUE MESSAGE THAT DATE IS */
                /* THAT DATE IS OUT OF UNION RANGE.                     */
                if  can-find(first mu_mstr where mu_union_curr  = curr1)
                and can-find(first mu_mstr where mu_member_curr = curr2)
                then do:
                   error-number = 2779.
                   /* DATE IS OUTSIDE THE UNION DATE RANGE */
                   return.
                end.   /* IF CAN-FIND... */

                /* IF CURR2 IS A UNION CURRENCY AND CURR1 IS A MEMBER   */
                /* CURRENCY AT ANY TIME THEN ISSUE MESSAGE THAT DATE IS */
                /* THAT DATE IS OUT OF UNION RANGE.                     */
                if  can-find(first mu_mstr where mu_union_curr  = curr2)
                and can-find(first mu_mstr where mu_member_curr = curr1)
                then do:
                   error-number = 2779.
                   /* DATE IS OUTSIDE THE UNION DATE RANGE */
                   return.
                end.   /* IF CAN-FIND... */

                if can-find(first mu_mstr where mu_union_curr = curr1)
                or can-find(first mu_mstr where mu_union_curr = curr2) then
                   error-number = 2780.
                   /* ONE CURRENCY MUST BE A UNION MEMBER OR BASE CURRENCY */
                else
                   error-number = 2666.
                   /* ONE CURRENCY MUST BE THE UNION OR BASE CURRENCY */
                return.
             end.  /* NOT CURR1 IS BASE AND... */

             /* IF ONE CURRENCY IS MEMBER CURRENCY, OTHER MUST BE UNION  */
             if (curr1-is-member and not curr2-is-union)
             or (curr2-is-member and not curr1-is-union) then do:
                for first mu_mstr fields (mu_member_curr mu_start_date
                mu_end_date) no-lock where mu_member_curr =
                (if curr1-is-member then curr1 else curr2)
                and mu_start_date <= i-date
                and mu_end_date >= i-date:  end.

                if available mu_mstr then
                   assign
                      error-number =  2954
                      error-parm1  = mu_member_curr.
                      /* # IS A MEMBER OF THE UNION DURING THIS DATE RANGE */
                else
                   error-number = 2664.
                   /* MEMBER CURR CAN ONLY HAVE DIRECT EXCH RATE WITH UNION */
                return.
             end.  /* IF (CURR1-IS-MEMBER...  */

          END PROCEDURE.  /* IP-CHK-CURR-RELATIONS */

          /*----------------------------------------------------------*/

          PROCEDURE ip-edit-start-date:
             /* EDIT START DATE ENTERED                     */
             /* RETURN ERROR NUMBER OF ANY ERROR DETECTED   */
             /* VIA OUTPUT PARAMETERS:                      */
             /*    ERROR-NUMBER   - MESSAGE#                */
             /*    ERROR-PARM1    - MESSAGE PARAMETER #1    */
             /* INPUT PARAMETER   - START-DATE              */

             define input  parameter ip-start-date      as date    no-undo.
             define buffer           exrrate            for exr_rate.

             assign error-number = 0
                    error-parm1 = "".

             /* DON'T ALLOW BLANK DATE  */
             if ip-start-date = ? then do:
                error-number =  482.
                /* START DATE CANNOT BE BLANK */
                return.
             end.

             /* DON'T ALLOW OVERLAP WITH ANY EXISTING EXCHANGE RATES */
             do for exrrate:
                if can-find(first exrrate where
                ((exr_curr1 = curr1 and exr_curr2  = curr2)
                or (exr_curr1 = curr2 and exr_curr2  = curr1))
                and exr_ratetype  = ""
                and exr_start_date < ip-start-date
                and exr_end_date >= ip-start-date)
                then do:
                   error-number = 122.
                   /*DATE RANGES MAY NOT OVERLAP*/
                   return.
                end.   /* IF CAN FIND EXRRATE... */
             end.   /* DO FOR EXRRATE... */

             /* CHECK IF CURRENCIES ARE UNION, MEMBER OR BASE FOR START DATE */
             run ip-chk-currs-this-date
                 (input ip-start-date).

             assign
                curr1-is-base = (curr1 = base_curr)
                curr2-is-base = (curr2 = base_curr)
                curr1-is-union-start  = curr1-is-union
                curr2-is-union-start  = curr2-is-union
                curr1-is-member-start = curr1-is-member
                curr2-is-member-start = curr2-is-member.

             /* CHECK RELATIONSHIP BETWEEN CURRENCIES FOR START DATE */
             run ip-chk-curr-relations
                 (input ip-start-date).

             /* IF ONE CURRENCY IS UNION CURRENCY, OTHER CURRENCY IS NOT A  */
             /* MEMBER CURRENCY, AND BASE CURRENCY IS NOT A MEMBER, AND     */
             /* NEITHER IS BASE CURRENCY, THEN ISSUE ERROR MESSAGE.         */
             if not base-is-member and not curr1-is-base
             and not curr2-is-base then do:
                if (curr1-is-union and
                not curr2-is-member) or
                (curr2-is-union and
                not curr1-is-member) then do:
                   assign
                      error-number = 2785
                      error-parm1  = if curr1-is-union then curr2
                                     else curr1.
                      /* # IS NOT A MEMBER OF THE UNION FOR THIS DATE RANGE */
                   return.
                end.  /* IF (CURR1-IS-UNION... */
             end.  /* IF NOT BASE-IS-MEMBER... */

          END PROCEDURE.  /* IP-EDIT-START-DATE */

          /*----------------------------------------------------------*/

          PROCEDURE ip-edit-end-date:
             /* EDIT END DATE ENTERED                       */
             /* RETURN ERROR NUMBER OF ANY ERROR DETECTED   */
             /* VIA OUTPUT PARAMETERS:                      */
             /*    ERROR-NUMBER   - MESSAGE#                */
             /*    ERROR-PARM1    - MESSAGE PARAMETER #1    */
             /* INPUT PARAMETERS:                           */
             /*    START-DATE                               */
             /*    END-DATE                                 */

             define input  parameter ip-start-date    as date    no-undo.
             define input  parameter ip-end-date      as date    no-undo.

             define buffer           exrrate          for exr_rate.

             assign error-number = 0
                    error-parm1 = "".

             /* DON'T ALLOW BLANK DATES  */
             if ip-end-date = ? then do:
                error-number = 711.
                /* DATE REQUIRED */
                return.
             end.   /* IF INPUT EXR_END_DATE = ?... */

             /* VALIDATE END DATE >= BEGIN DATE */
             if ip-start-date > ip-end-date then do:
                error-number =  123.
                /* END DATE CANNOT BE BEFORE START DATE */
                return.
             end.

             /* CHECK OVERLAPPING DATES                             */

/*M0GM*/     /* MODIFIED DATE OVERLAP LOGIC WHILE ENTERING END DATE */

             do for exrrate:
                find first exrrate
                where ((exr_curr1 = curr1 and exr_curr2 = curr2)
                or (exr_curr1 = curr2 and exr_curr2 = curr1))
                and exr_ratetype = ""
/*M0GM**        and exr_start_date < ip-end-date                    */
/*M0GM**        and exr_end_date > ip-end-date no-lock no-error.    */
/*M0GM*/        and exr_start_date <= ip-end-date
/*M0GM*/        and exr_end_date   >= ip-start-date
/*M0GM*/        no-lock no-error.

                if available exrrate then
                   if save-end-date = ?     /* NEW RECORD */
                   or (save-end-date <> ?   /* MODIFYING EXISTING RECORD */
                   and recid(exrrate) <> recid(exr_rate))
                   /* RECORD FOUND IS NOT SAME RECORD BEING MODIFIED */
                   then do:
                      error-number = 122.
                      /* DATE RANGES MAY NOT OVERLAP */
                      return.
                   end.   /* IF SAVE-END-DATE = ? ... */
             end.   /* DO FOR EXRRATE... */

             /* CHECK IF CURRENCIES ARE UNION, MEMBER OR BASE FOR END DATE */
             run ip-chk-currs-this-date
                 (input ip-end-date).

             assign
                curr1-is-union-end  = curr1-is-union
                curr2-is-union-end  = curr2-is-union
                curr1-is-member-end = curr1-is-member
                curr2-is-member-end = curr2-is-member.

             /* CHECK RELATIONSHIP BETWEEN CURRENCIES FOR END DATE */
             run ip-chk-curr-relations
                 (input ip-end-date).

          END PROCEDURE.  /* IP-EDIT-END-DATE */

          /*----------------------------------------------------------*/

          PROCEDURE ip-chk-date-range:

             /* VALIDATES CURRENCY RELATIONSHIP ACROSS DATE RANGE */
             /* RETURN ERROR NUMBER OF ANY ERROR DETECTED         */
             /* VIA OUTPUT PARAMETERS:                            */
             /*    ERROR-NUMBER   - MESSAGE#                      */
             /*    ERROR-PARM1    - MESSAGE PARAMETER #1          */
             /* INPUT PARAMETERS:                                 */
             /*    START-DATE                                     */
             /*    END-DATE                                       */

             define input  parameter ip-start-date    as date    no-undo.
             define input  parameter ip-end-date      as date    no-undo.

             define buffer mumstr for mu_mstr.

             assign error-number = 0
                    error-parm1 = "".

             /* WHEN ONE CURRENCY IS BASE CURRENCY AND THE OTHER CURRENCY */
             /* IS NEVER A MEMBER CURRENCY, THEN ALL RATES POSSIBLE.  NO  */
             /* FURTHER VALIDATION REQUIRED.                              */
             if not base-is-member-ever and
             ((curr1-is-base and not curr2-is-member-ever) or
             (curr2-is-base and not curr1-is-member-ever)) then
                return.

             /* IF ONE CURRENCY IS THE UNION CURRENCY ON START DATE, THEN IT */
             /* MUST ALSO BE THE UNION CURRENCY ON END DATE.  LIKEWISE,      */
             /* IF ONE CURRENCY IS A MEMBER CURRENCY ON START DATE, THEN IT  */
             /* MUST ALSO BE A MEMBER CURRENCY ON END DATE.                  */
             if (curr1-is-union-start and not curr1-is-union-end)
             or (not curr1-is-union-start and curr1-is-union-end)
             or (curr2-is-union-start and not curr2-is-union-end)
             or (not curr2-is-union-start and curr2-is-union-end)
             then do:
                error-number = 2779.
                /* DATE IS OUTSIDE THE UNION DATE RANGE */
                return.
             end.

             if (curr1-is-member-start and not curr1-is-member-end)
             or (not curr1-is-member-start and curr1-is-member-end)
             or (curr2-is-member-start and not curr2-is-member-end)
             or (not curr2-is-member-start and curr2-is-member-end)
             then do:
                assign
                   error-number = 2785
                   error-parm1  =
                      if curr1-is-member-start or curr1-is-member-end then curr1
                      else
                      if curr2-is-member-start or curr2-is-member-end then curr2
                      else
                      if curr1-is-union-start or curr1-is-union-end then curr2
                      else
                      if curr2-is-union-start or curr2-is-union-end then curr1
                      else "".
                   /* # IS NOT A MEMBER OF THE UNION FOR THIS DATE RANGE */
                return.
             end.

             /* WHEN ONE CURRENCY IS THE UNION AND THE OTHER IS A MEMBER */
             /* FOR THE DATE RANGE ENTERED, CHECK IF THERE IS A GAP IN   */
             /* UNION PARTICIPATION FOR THE MEMBER CURRENCY.             */
             /* FOR EXAMPLE, DEM IS IN UNION FROM 01/01/99 THRU 12/31/99 */
             /* AND AGAIN BETWEEN 01/01/01 THRU 07/01/02, BUT NOT DURING */
             /* 01/01/00 THRU 12/31/00.  SO DEM CANNOT BE DEFINED TO THE */
             /* UNION FOR A DATE RANGE THAT SPANS THE YEAR 2000. THIS    */
             /* DATE RANGE WOULD BE A MIXTURE OF UNION AND NON-UNION     */
             /* PARTICIPATION FOR DEM, AND THE DEM:EUR RATE WOULD NOT    */
             /* NECESSARILY BE THE SAME FOR BOTH SITUATIONS.             */
             if curr1-is-union-start and curr1-is-union-end
             and curr2-is-member-start and curr2-is-member-end then do:
                find first mu_mstr
                where mu_union_curr = curr1
                and mu_member_curr = curr2
                and mu_start_date <= ip-start-date
                and mu_end_date >= ip-start-date
                no-lock no-error.

                if available mu_mstr then
                   find first mumstr
                   where mumstr.mu_union_curr = curr1
                   and mumstr.mu_member_curr = curr2
                   and mumstr.mu_start_date <= ip-end-date
                   and mumstr.mu_end_date >= ip-end-date
                   no-lock no-error.

                if available mu_mstr and available mumstr and
                recid(mu_mstr) <> recid(mumstr) then do:
                   assign
                      error-number = 2785
                      error-parm1  = curr2.
                      /* # IS NOT A MEMBER OF THE UNION FOR THIS DATE RANGE */
                   return.
                end.
             end.   /* IF CURR1-IS-UNION-START AND CURR1-IS-UNION-END... */

             if curr2-is-union-start and curr2-is-union-end
             and curr1-is-member-start and curr1-is-member-end then do:
                find first mu_mstr
                where mu_mstr.mu_union_curr = curr2
                and mu_mstr.mu_member_curr = curr1
                and mu_mstr.mu_start_date <= ip-start-date
                and mu_mstr.mu_end_date >= ip-start-date
                no-lock no-error.

                if available mu_mstr then
                   find first mumstr
                   where mumstr.mu_union_curr = curr2
                   and mumstr.mu_member_curr = curr1
                   and mumstr.mu_start_date <= ip-end-date
                   and mumstr.mu_end_date >= ip-end-date
                   no-lock no-error.

                if available mu_mstr and available mumstr and
                recid(mu_mstr) <> recid(mumstr) then do:
                   assign
                      error-number = 2785
                      error-parm1  = curr1.
                      /* # IS NOT A MEMBER OF THE UNION FOR THIS DATE RANGE */
                   return.
                end.
             end.   /* IF CURR2-IS-UNION-START AND CURR2-IS-UNION-END... */

             /**************************************************************/
             /* VALIDATIONS WHEN BASE IS NEITHER UNION NOR MEMBER CURRENCY */
             /* OR WHEN BASE IS MEMBER CURRENCY AT SOME DATE.              */
             if base-is-neither or base-is-member-ever then do:

                /* IF ONE CURRENCY IS BASE AND THE OTHER NON-BASE AND THE  */
                /* NON-BASE CURRENCY IS NOT A MEMBER CURRENCY AT START AND */
                /* END DATES, BUT NON-BASE CURRENCY IS A MEMBER SOMETIME,  */
                /* SEE IF NON-BASE CURRENCY IS A MEMBER BETWEEN THE DATES  */
                /* ENTERED.                                                */
                /* FOR EXAMPLE, NLG IS BASE CURRENCY AND IS A MEMBER FROM  */
                /* 01/01/99 THRU 07/01/02.  DEM IS A MEMBER FROM 01/01/99  */
                /* THRU 12/31/99 AND AGAIN BETWEEN 01/01/01 THRU 07/01/02, */
                /* BUT NOT DURING 01/01/00 THRU 12/31/00.  THE UNION RUNS  */
                /* FROM 01/01/99 THRU 07/01/02.  NLG:DEM IS NOT ALLOWED    */
                /* FOR A PERIOD SPANNING 12/31/98 THRU 07/02/02 BECAUSE    */
                /* DEM IS PERIODICALLY A UNION MEMBER BETWEEN THOSE DATES. */
                if curr1-is-base and curr2-is-member-ever
                and (not curr2-is-member-start or not curr2-is-member-end)
                then do:
                   if can-find (first mu_mstr
                   where mu_member_curr = curr2
                   and (mu_start_date >= ip-start-date
                   and mu_end_date <= ip-end-date))
                   then do:
                      assign
                         error-number = 2954
                         error-parm1  = curr2.
                         /* # IS A MEMBER OF THE UNION DURING THIS DATE RANGE */
                      return.
                   end.
                end.   /* IF CURR1-IS-BASE AND CURR2-IS-MEMBER-EVER... */

                if curr2-is-base and curr1-is-member-ever
                and (not curr1-is-member-start or not curr1-is-member-end)
                then do:
                   if can-find (first mu_mstr
                   where mu_member_curr = curr1
                   and (mu_start_date >= ip-start-date
                   and mu_end_date <= ip-end-date))
                   then do:
                      assign
                         error-number = 2954
                         error-parm1  = curr1.
                         /* # IS A MEMBER OF THE UNION DURING THIS DATE RANGE */
                      return.
                   end.
                end.   /* IF CURR2-IS-BASE AND CURR1-IS-MEMBER-EVER... */

             end.   /* IF BASE-IS-NEITHER OR BASE-IS-MEMBER-EVER */

             /**************************************************************/
             /* ADDITIONAL VALIDATIONS WHEN BASE IS MEMBER CURRENCY */
             if base-is-member-ever then do:

                /* IF ONE CURRENCY IS BASE AND THE OTHER NON-BASE, IF THE  */
                /* BASE CURRENCY IS A MEMBER SOMETIME, BUT NOT AT START    */
                /* END DATES, SEE IF THE BASE CURRENCY IS A MEMBER         */
                /* BETWEEN THE DATES ENTERED.                              */
                /* FOR EXAMPLE, NLG IS BASE CURRENCY AND IS A MEMBER FROM  */
                /* 01/01/99 THRU 07/01/02.  CDN IS NEVER A MEMBER OR UNION */
                /* CURRENCY.  NLG:CDN IS ALLOWED FOR ANY DATES STARTING    */
                /* ENDING BEFORE 01/01/99 OR, FOR ANY DATES STARTING AND   */
                /* ENDING AFTER 07/01/02.  BUT, NLG:CDN IS NOT ALLOWED FOR */
                /* 12/31/98 THRU 07/02/02 BECAUSE NLG IS A MEMBER BETWEEN  */
                /* 01/01/99 THRU 07/01/02.                                 */
                if curr1-is-base and curr1-is-member-ever
                and (not curr1-is-member-start or not curr1-is-member-end)
                then do:
                   if can-find (first mu_mstr
                   where mu_member_curr = curr1
                   and (mu_start_date >= ip-start-date
                   and mu_end_date <= ip-end-date))
                   then do:
                      error-parm1  = curr1.
                      if curr2-is-union-ever or not curr2-is-member-ever then
                         error-number = 2954.
                         /* # IS A MEMBER OF THE UNION DURING THIS DATE RANGE */
                      else
                         error-number = 2785.
                        /* # IS NOT A MEMBER OF THE UNION FOR THIS DATE RANGE */
                      return.
                   end.
                end.   /* IF CURR1-IS-BASE AND CURR1-IS-MEMBER-EVER... */

                if curr2-is-base and curr2-is-member-ever
                and (not curr2-is-member-start or not curr2-is-member-end)
                then do:
                   if can-find (first mu_mstr
                   where mu_member_curr = curr2
                   and (mu_start_date >= ip-start-date
                   and mu_end_date <= ip-end-date))
                   then do:
                      error-parm1  = curr2.
                      if curr1-is-union-ever or not curr1-is-member-ever then
                         error-number = 2954.
                         /* # IS A MEMBER OF THE UNION DURING THIS DATE RANGE */
                      else
                         error-number = 2785.
                        /* # IS NOT A MEMBER OF THE UNION FOR THIS DATE RANGE */
                      return.
                   end.
                end.   /* IF CURR2-IS-BASE AND CURR2-IS-MEMBER-EVER... */

                /* IF NEITHER CURRENCY IS THE UNION OR MEMBER CURRENCY AT     */
                /* START AND AT END DATES, BUT ONE CURRENCY IS THE UNION FOR  */
                /* SOME DATE, SEE IF IT IS THE UNION BETWEEN THE DATES ENTERED*/
                if curr1-is-base and curr2-is-union-ever
                and (not curr2-is-union-start or not curr2-is-union-end)
                then do:
                   if can-find (first mu_mstr
                   where mu_union_curr = curr2
                   and (mu_start_date >= ip-start-date
                   and mu_end_date <= ip-end-date))
                   then do:
                      assign
                         error-number = 2785
                         error-parm1  = curr2.
                        /* # IS NOT A MEMBER OF THE UNION FOR THIS DATE RANGE */
                      return.
                   end.
                end.   /* IF CURR1-IS-BASE AND CURR2-IS-UNION-EVER... */

                if curr2-is-base and curr1-is-union-ever
                and (not curr1-is-union-start or not curr1-is-union-end)
                then do:
                   if can-find (first mu_mstr
                   where mu_union_curr = curr1
                   and (mu_start_date >= ip-start-date
                   and mu_end_date <= ip-end-date))
                   then do:
                      assign
                         error-number = 2785
                         error-parm1  = curr1.
                        /* # IS NOT A MEMBER OF THE UNION FOR THIS DATE RANGE */
                      return.
                   end.
                end.   /* IF CURR2-IS-BASE AND CURR1-IS-UNION-EVER... */

             end.   /* IF BASE-IS-MEMBER-EVER */

             /**************************************************************/
             /* VALIDATIONS WHEN BASE IS UNION CURRENCY */
             if base-is-union-ever then do:

                /* IF NEITHER CURRENCY IS THE UNION OR MEMBER CURRENCY AT     */
                /* START AND AT END DATES, SEE IF ONE OF THE CURRENCIES IS A  */
                /* A MEMBER BETWEEN THE DATES ENTERED.                        */
                if (not curr1-is-union-start or not curr1-is-union-end)
                and (not curr2-is-member-start or not curr2-is-member-end)
                then do:
                   if can-find (first mu_mstr
                   where mu_union_curr = curr1
                   and mu_member_curr = curr2
                   and (mu_start_date <= ip-start-date
                   or  mu_end_date <= ip-end-date))
                   and can-find (first mu_mstr
                   where mu_union_curr = curr1
                   and mu_member_curr = curr2
                   and (mu_start_date >= ip-start-date
                   or  mu_end_date >= ip-end-date))
                   then do:
                      assign
                         error-number = 2954
                         error-parm1  = curr2.
                        /* # IS A MEMBER OF THE UNION DURING THIS DATE RANGE */
                      return.
                   end.
                end.   /* IF (NOT CURR1-IS-UNION-START OR NOT CURR1... */

                if (not curr2-is-union-start or not curr2-is-union-end)
                and (not curr1-is-member-start or not curr1-is-member-end)
                then do:
                   if can-find (first mu_mstr
                   where mu_union = curr2
                   and mu_member_curr = curr1
                   and (mu_start_date <= ip-start-date
                   or  mu_end_date <= ip-end-date))
                   and can-find (first mu_mstr
                   where mu_union_curr = curr2
                   and mu_member_curr = curr1
                   and (mu_start_date >= ip-start-date
                   or  mu_end_date >= ip-end-date))
                   then do:
                      assign
                         error-number = 2954
                         error-parm1  = curr1.
                         /* # IS A MEMBER OF THE UNION DURING THIS DATE RANGE */
                      return.
                   end.
                end.   /* IF (NOT CURR2-IS-UNION-START OR NOT CURR2... */

             end.   /* IF BASE-IS-UNION-EVER */

          END PROCEDURE.  /* IP-CHK-DATE-RANGE */

          /*----------------------------------------------------------*/

/*L09G    **** OLD VERSION OF PROGRAM PRIOR TO *L09G*
 *
 *        define variable var-fld-match     as logical init yes  no-undo.
 *        /* NOTE REGARDING ABOVE VAR-FLD-MATCH VARIABLE:            */
 *        /* THIS VARIABLE FLAGS IF THE CURRENCY CODES/RATE AMOUNT   */
 *        /* VARIABLES ON THE SCREEN MATCH THE INTERNAL STORAGE ORDER*/
 *        /* OF CURRENCY CODES/RATE AMOUNTS FIELDS:                  */
 *        /*         IF VAR-FLD_MATCH = YES                          */
 *        /*            THEN EXR_CURR1     = CURR1                   */
 *        /*                 EXR_CURR2     = CURR2                   */
 *        /*                 EXR_RATE = RATE_AMT1                    */
 *        /*                 EXR_RATE2 = RATE_AMT2                   */
 *        /*            ELSE EXR_CURR1     = CURR2                   */
 *        /*                 EXR_CURR2     = CURR1                   */
 *        /*                 EXR_RATE = RATE_AMT2                    */
 *        /*                 EXR_RATE2 = RATE_AMT1                   */
 *
 *        define buffer exrrate         for exr_rate.
 *        define query q1 for exr_rate scrolling.
 *
 *        /* CREATE VARIABLES FOR TEMPORARY FILES USED IN THE AUDIT TRAIL */
 *        {gpaud.i &uniq_num1 = 1
 *                 &uniq_num2 = 2
 *                 &db_file   = exr_rate
 *                 &db_field  = exr_curr1}
 *
 *        /* DISPLAY SELECTION FORM */
 *        form
 *           curr1            colon 10 space(2)
 *           curr1-desc       no-label
 *           curr2            space(2)
 *           curr2-desc       no-label
 *        with frame a side-labels width 80.
 *
 *
 *        form  exr_start_date
 *              exr_end_date
 *              rate-amt1
 *              rate-amt2
 *        with frame b attr-space down width 80.
 *
 *     /* DISPLAY */
 *     mainloop: repeat on endkey undo, leave mainloop:
 *
 *       set curr1 with frame a editing:
 *          /* FIND NEXT/PREVIOUS RECORD */
 *          {mfnp.i cu_mstr curr1 cu_curr curr1 cu_curr cu_curr}
 *          if recno <> ? then do with frame a:
 *             assign curr1 = cu_curr
 *                    curr1-desc = cu_desc.
 *             display  curr1
 *                      curr1-desc.
 *          end.  /* IF RECNO <> ?... */
 *
 *       end.  /* SET FOR CU_CURR... */
 *
 *       /* CURR1 MUST BE VALID CURRENCY        */
 *       {gprunp.i "mcpl" "p" "mc-chk-valid-curr"
 *                    "(input curr1,
 *                      output error-number)"}
 *       if error-number = 3088 then do:
 *          {mfmsg.i error-number 3}
 *          /* INVALID/INACTIVE CURRENCY */
 *          next-prompt curr1 with frame a.
 *          undo mainloop, retry mainloop.
 *       end.  /* ERROR-NUMBER = 3088... */
 *
 *       /* IF CURR1 IS INACTIVE, ISSUE WARNING  */
 *       if error-number = 2659 then do:
 *          chg-ok = no.
 *          {mfmsg01.i 2668 2 chg-ok}
 *          /* WARNING: THIS CURRENCY IS INACTIVE. CONTINUE?   */
 *          if not chg-ok then do:
 *              next-prompt curr1 with frame a.
 *              undo mainloop, retry mainloop.
 *          end.
 *       end.  /* ERROR-NUMBER = 2659... */
 *
 *       /* DISPLAY CURR1 DESCRIPTION    */
 *       for first cu_mstr no-lock where cu_curr = curr1:
 *          display cu_desc @ curr1-desc with frame a.
 *       end.
 *
 *       setcurr2: do on error undo, retry:
 *          set curr2 with frame a editing:
 *             /* FIND NEXT/PREVIOUS RECORD */
 *             {mfnp.i cu_mstr curr2 cu_curr curr2 cu_curr cu_curr}
 *             if recno <> ? then do with frame a:
 *             assign curr2 = cu_curr
 *                    curr2-desc = cu_desc.
 *                display  curr2
 *                         curr2-desc.
 *             end.  /* IF RECNO <> ?... */
 *
 *          end.  /* SET FOR CU_CURR... */
 *
 *          /* CURR2 MUST BE VALID AND ACTIVE CURRENCY      */
 *          {gprunp.i "mcpl" "p" "mc-chk-valid-curr"
 *                    "(input curr2,
 *                      output error-number)"}
 *          if error-number = 3088 then do:
 *             {mfmsg.i error-number 3}
 *             /* INVALID/INACTIVE CURRENCY */
 *             next-prompt curr2 with frame a.
 *             undo setcurr2, retry.
 *          end.  /* IF ERROR-NUMBER = 3088... */
 *
 *          /* IF CURR2 IS INACTIVE, ISSUE WARNING  */
 *          if error-number = 2659 then do:
 *             chg-ok = no.
 *             {mfmsg01.i 2668 2 chg-ok}
 *             /* WARNING: THIS CURRENCY IS INACTIVE. CONTINUE?   */
 *             if not chg-ok then do:
 *                 next-prompt curr2 with frame a.
 *                 undo setcurr2, retry.
 *             end.
 *          end.  /* IF ERROR-NUMBER = 2659... */
 *
 *          /* DISPLAY CURR2 DESCRIPTION    */
 *          for first cu_mstr no-lock where cu_curr = curr2:
 *             display cu_desc @ curr2-desc with frame a.
 *          end.
 *
 *          /* CURR1 CANNOT BE SAME AS CURR2    */
 *          if curr1 = curr2  then do:
 *               {mfmsg.i 2670 3}
 *               /* BOTH CURRENCIES CANNOT BE THE SAME CURRENCY CODE */
 *               next-prompt curr2 with frame a.
 *               undo setcurr2, retry.
 *          end.  /* ERROR-NUMBER <> 0... */
 *
 *       end.  /* setcurr2 */
 *
 *       /* VAR-FLD-MATCH SET IF ORDER OF CURRENCIES ON  */
 *       /* THE FRAME MATCHES THE ORDER OF CURRENCIES IN */
 *       /* THE EXR_RATE FILE.                           */
 *       var-fld-match = can-find(first exr_rate
 *          where exr_curr1 = curr1
 *          and   exr_curr2 = curr2).
 *       /* USE QUERY TO RETRIEVE RECORDS TO BE DISPLAYED */
 * /*L06X* *QUERIES NEED TO BE WRAPPED IN DO STATEMENT FOR GUI REQUIREMENTS */
 * /*L06X* *if var-fld-match then */
 * /*L06X*/ *  if var-fld-match then do:
 *          open query q1 for each exr_rate no-lock
 *               where exr_curr1 = curr1
 *               and   exr_curr2 = curr2
 *               by exr_start_date.
 * /*L06X*/ *  end.
 * /*L06X* *else  */
 * /*L06X*/ *  else do:
 *          open query q1 for each exr_rate no-lock
 *               where exr_curr1 = curr2
 *               and   exr_curr2 = curr1
 *               by exr_start_date.
 * /*L06X*/ *  end.
 *
 *       assign i = 11
 *              recnum = 0.
 *
 *       get last q1.
 *
 *       do while available exr_rate:
 *          assign i = i - 1
 *                 recnum[i] = recid(exr_rate).
 *          if i = 1 then leave.
 *          get prev q1.
 *       end.   /* DO WHILE AVAILABLE EXR_RATE... */
 *
 *
 *       if i <> 11 then do:
 *          do i = 1 to 10:
 *             if recnum[i] = 0 then next.
 *             reposition q1 to recid recnum[i].
 *             get next q1.
 *             assign rate-amt1 = if var-fld-match then exr_rate
 *                                                 else exr_rate2
 *                    rate-amt2 = if var-fld-match then exr_rate2
 *                                                 else exr_rate.
 *             display exr_start_date exr_end_date rate-amt1 rate-amt2
 *                     with down frame b.
 *             down 1 with frame b.
 *          end.   /* DO I = 1 TO 10...   */
 *          next-start = exr_end_date + 1.
 *       end.     /* IF I <> 11... */
 *       else next-start = today.
 *
 * /*L04F* *loopb:  repeat with frame b width 80:  */
 * /*L04F*/ *  loopb:  repeat:
 * /*L04F*/ *innerloop: repeat with frame b width 80
 * /*L04F*/ *            on endkey undo, leave loopb:
 *
 *         /* HEADING IN FRAME IS CONCATENATION OF CAPITALIZED CURRENCY CODE  */
 *         /*  and "Units"                                                   */
 *          assign
 *          rate-amt1:label = caps(string(curr1)) + " " + {&mcexrmt_p_1}
 *          rate-amt2:label = "  " + caps(string(curr2)) +  " " +
 *                            {&mcexrmt_p_1}.
 *
 *          display next-start @ exr_start_date.
 *
 *          dateframe: do on endkey undo loopb, leave
 *                        on error undo, retry:
 *
 *             prompt-for exr_start_date editing:
 *                 ststatus = stline[1].
 *                 status input ststatus.
 *                 readkey.
 *                 hide message no-pause.
 *
 *                 /* FIND NEXT/PREV RECORD */
 *                 /* NOTE: STANDARD MFNP.I NOT USED BECAUSE OF THE   */
 *                 /* NEED TO POSSIBLY 'FLIP' THE EXCHANGE RATE       */
 *                 /* BASED ON VALUE OF FIELD 'VAR-FLD-MATCH'         */
 *                 if lastkey = keycode("F10")
 *                 or keyfunction(lastkey) = "CURSOR-DOWN"
 *                 then do:
 *                    if recno = ? then get first q1.
 *                    else get next q1.
 *                    if not available exr_rate then do:
 *                       {mfmsg.i 20 2}  /* End of file */
 *                       if recno = ? then get last q1.
 *                       else if recno <> ? then do:
 *                         reposition q1 to recid recno.
 *                         get next q1.
 *                       end.
 *                       input clear.
 *                     end.     /* IF NOT AVAILABLE EXR_RATE...     */
 *                     recno = recid(exr_rate).
 *                 end.   /* LASTKEY = KEYCODE("F10")... */
 *
 *                 /* FIND PREVIOUS RECORD  */
 *                 else if lastkey = keycode("F9")
 *                       or keyfunction(lastkey) = "CURSOR-UP"
 *                 then do:
 *                    if recno = ? then get last q1.
 *                    else get prev q1.
 *                    if not available exr_rate then do:
 *                       {mfmsg.i 21 2}  /* Beginning of file */
 *                      if recno = ? then get first q1.
 *                      else if recno <> ? then do:
 *                         reposition q1 to recid recno.
 *                         get next q1.
 *                       end.
 *                      input clear.
 *                    end.
 *                    recno = recid(exr_rate).
 *                 end.   /* LASTKEY = KEYCODE("F9")... */
 *
 *                 /* INPUT PROMPT FIELD */
 *                 else do:
 *                    recno = ?.
 *                    if keyfunction(lastkey) = "end-error" then do:
 *                       ststatus = stline[3].
 *                       status input ststatus.
 *                    end.  /* LASTKEY = "END-ERROR"... */
 *                    apply lastkey.
 *                 end.   /* ELSE DO...  */
 *
 *                 if available exr_rate then do:
 *                    if var-fld-match then
 *                    assign  rate-amt1 = exr_rate
 *                            rate-amt2 = exr_rate2.
 *                    else assign rate-amt1 = exr_rate2
 *                                rate-amt2 = exr_rate.
 *
 *                    if recno <> ? then display exr_start_date
 *                                               exr_end_date
 *                                               rate-amt1
 *                                               rate-amt2.
 *                 end.   /* IF AVAILABLE EXR_RATE... */
 *             end.    /* PROMPT-FOR EXR_START_DATE EDITING... */
 *
 *             /* EDIT START DATE ENTERED */
 *             /* DON'T ALLOW BLANK DATE  */
 *             if input exr_rate.exr_start_date = ? then do:
 *                {mfmsg.i 482 3} /* START DATE CANNOT BE BLANK */
 *                next-prompt exr_start_date with frame b.
 *                undo, retry.
 *             end.
 *
 *             /* DON'T ALLOW OVERLAP WITH ANY EXISTING EXCHANGE RATES */
 *             do for exrrate:
 *              if (var-fld-match and can-find(first exrrate where
 *                    exr_curr1 = curr1
 *                and exr_curr2  = curr2
 *                and exr_ratetype  = ""
 *                and exr_start_date < input exr_rate.exr_start_date
 *                and exr_end_date >= input exr_rate.exr_start_date))
 *                or
 *                  (not var-fld-match and can-find(first exrrate where
 *                    exr_curr1 = curr2
 *                and exr_curr2  = curr1
 *                and exr_ratetype  = ""
 *                and exr_start_date < input exr_rate.exr_start_date
 *                and exr_end_date >= input exr_rate.exr_start_date))
 *                then do:
 *                     {mfmsg.i 122 3}
 *                     /*DATE RANGES MAY NOT OVERLAP*/
 *                     undo, retry.
 *                end.   /* IF AVAILABLE EXRRATE... */
 *             end.   /* DO FOR EXRRATE... */
 *
 *             /* DETERMINE IF CURRENCIES ARE UNION, MEMBER, OR BASE CURR */
 *             /* IN AFFECT AT THE START DATE                             */
 *             {gprunp.i "mcpl" "p" "mc-chk-union-curr"
 *                       "(input curr1,
 *                         input input exr_start_date,
 *                         output curr1-is-union)"}
 *
 *             {gprunp.i "mcpl" "p" "mc-chk-union-curr"
 *                       "(input curr2,
 *                         input input exr_start_date,
 *                         output curr2-is-union)"}
 *
 *             {gprunp.i "mcpl" "p" "mc-chk-member-curr"
 *                       "(input curr1,
 *                         input input exr_start_date,
 *                         output union-curr,
 *                         output curr1-is-member)"}
 *
 *             {gprunp.i "mcpl" "p" "mc-chk-member-curr"
 *                       "(input curr2,
 *                         input input exr_start_date,
 *                         output union-curr,
 *                         output curr2-is-member)"}
 *
 *              assign curr1-is-base = (curr1 = base_curr)
 *                     curr2-is-base = (curr2 = base_curr).
 *
 *             /* ONE OF THE CURRENCIES MUST BE THE BASE */
 *             /* OR THE UNION CURRENCY                  */
 *             if not curr1-is-base and
 *                not curr1-is-union and
 *                not curr2-is-base and
 *                not curr2-is-union then do:
 *                   {mfmsg.i 2666 3}
 *                   /* ONE CURRENCY MUST BE EITHER UNION OR BASE CURRENCY  */
 *                   next-prompt exr_start_date with frame b.
 *                   undo, retry.
 *             end.  /* NOT CURR1... */
 *
 *             /* IF ONE CURRENCY IS MEMBER CURRENCY, OTHER MUST BE UNION  */
 *             if (curr1-is-member and
 *                not curr2-is-union) or
 *                (curr2-is-member and
 *                not curr1-is-union) then do:
 *                   {mfmsg.i 2664 3}
 *             /* MEMBER CURR CAN ONLY HAVE DIRECT EXCH RATE WITH UNION CURR */
 *                   next-prompt exr_start_date with frame b.
 *                   undo, retry.
 *             end.  /* IF (CURR1-IS-MEMBER...  */
 *
 *
 *             /* FIND EXISTING RECORD TO MODIFY */
 *             if var-fld-match then do:
 *                for first exr_rate exclusive-lock
 *                    where exr_curr1 = curr1
 *                    and exr_curr2 = curr2
 *                    and exr_ratetype = ""
 *                    and exr_start_date = input exr_start_date: end.
 *             end.  /* IF VAR-FLD-MATCH... */
 *             else do:
 *                for first exr_rate exclusive-lock
 *                    where exr_curr1 = curr2
 *                    and exr_curr2 = curr1
 *                    and exr_ratetype = ""
 *                    and exr_start_date = input exr_start_date: end.
 *             end.  /* IF NOT VAR-FLD-MATCH... */
 *             if available exr_rate then do:
 *                {mfmsg.i 10 1} /*MODIFYING EXISTING RECORD*/
 *                assign save-end-date  = exr_end_date
 *                       save-rate-amt1 = if var-fld-match
 *                                        then exr_rate else exr_rate2
 *                       save-rate-amt2 = if var-fld-match
 *                                        then exr_rate2 else exr_rate.
 *             end.
 *             else do:
 *                /* ADD RECORD */
 *                {mfmsg.i 1 1} /* ADDING NEW RECORD */
 *                create exr_rate.
 *                assign exr_curr1 = if var-fld-match then curr1 else curr2
 *                       exr_curr2 = if var-fld-match then curr2 else curr1
 *                       exr_ratetype   = ""
 *                       exr_start_date = input exr_start_date
 *                       exr_end_date   = input exr_start_date.
 *
 *                if recid(exr_rate) = -1 then .
 *             end.   /* ELSE DO... */
 *
 *             /* TIMESTAMP RECORD */
 *             assign exr_mod_date   = today
 *                    exr_mod_userid = global_userid
 *                    recno = recid(exr_rate).
 *
 *             /* AUDIT TRAIL RECORDS WILL BE CREATED    */
 *             /* TO CAPTURE THE BEFORE IMAGE            */
 *             {gpaud1.i &uniq_num1 = 1
 *                       &uniq_num2 = 2
 *                       &db_file   = exr_rate
 *                       &db_field  = exr_curr1
 *                       &db_field1 = exr_curr2}
 *
 *             ststatus = stline[2].
 *             status input ststatus.
 *             assign del-yn = no
 *                    rate-amt1 = if var-fld-match
 *                                then exr_rate else exr_rate2
 *                    rate-amt2 = if var-fld-match
 *                                then exr_rate2 else exr_rate
 *                    is-EMU-exch-rate = no.
 *
 *             /* CHECK IF CURR1 IS A UNION CURRENCY            */
 *             /* AND IF CURR2 IS A MEMBER OF THAT UNION        */
 *             /* IF SO, SET VALUE TO 1.0 AND INHIBIT INPUT     */
 *             if curr1-is-union and curr2-is-member
 *             then assign rate-amt1 = 1.0
 *                         is-EMU-exch-rate = yes.
 *
 *             /* CHECK IF CURR2 IS A UNION CURRENCY            */
 *             /* AND IF CURR1 IS A MEMBER OF THAT UNION        */
 *             /* IF SO, SET VALUE TO 1.0 AND INHIBIT INPUT     */
 *             if curr2-is-union and curr1-is-member
 *             then assign rate-amt2 = 1.0
 *                         is-EMU-exch-rate = yes.
 *
 *             display exr_end_date
 *                     rate-amt1
 *                     rate-amt2.
 *
 *             setb: do on error undo, retry:
 *                prompt-for exr_end_date go-on (F5 CTRL-D).
 *                /* CHECK FOR DELETE REQUEST */
 *
 *                if lastkey = keycode("F5") or lastkey = keycode("CTRL-D")
 *                   then do:
 *                   del-yn = yes.
 *                   {mfmsg01.i 11 1 del-yn} /*CONFIRM DELETE*/
 *                end.
 *                if del-yn then do:
 *                   /* ISSUE WARNING MESSAGE IF END DATE  */
 *                   /* < OR = TODAY                       */
 *                   if input exr_end_date <= today then do:
 *                      del-yn = no.
 *                      {mfmsg01.i 2660 2 del-yn}
 *                      /* WARNING: DELETION COULD AFFECT      */
 *                      /* EXISTING TRANSACTIONS. CONTINUE?    */
 *                   end.    /* IF EXR_END_DATE <= TODAY..     */
 *
 *                   if del-yn then do:
 *                      delete exr_rate.
 *                        clear frame b.
 *                        assign recno = ?
 *                               del-yn = no.
 * /*L04F* *                 next loopb.  */
 * /*L04F*/ *                leave innerloop.
 *                   end.    /* IF DEL-YN... */
 *                end.    /* IF DEL-YN... */
 *
 *                /* VALIDATE END DATE ENTERED */
 *                /* DON'T ALLOW BLANK DATES  */
 *                if input exr_end_date = ? then do:
 *                   {mfmsg.i 711 3} /* DATE REQUIRED */
 *                   next-prompt exr_end_date with frame b.
 *                   undo setb, retry.
 *                end.   /* IF INPUT EXR_END_DATE = ?... */
 *
 *                assign exr_end_date.
 *
 *                /* VALIDATE END DATE >= BEGIN DATE */
 *                if exr_start_date > exr_end_date then do:
 *                     {mfmsg.i 123 3}
 *                     /* END DATE CANNOT BE BEFORE END DATE */
 *                     next-prompt exr_end_date with frame b.
 *                     undo setb, retry.
 *                end.
 *
 *                /* CHECK OVERLAPPING DATES   */
 *                    if can-find(first exrrate
 *                where exrrate.exr_curr1 = exr_rate.exr_curr1
 *                  and exrrate.exr_curr2 = exr_rate.exr_curr2
 *                  and exrrate.exr_ratetype = ""
 *                  and exr_rate.exr_start_date <= exrrate.exr_end_dat
 *                  and exr_rate.exr_end_date >= exrrate.exr_start_date
 *                  and recid(exrrate) <> recid(exr_rate))
 *                then do:
 *                  {mfmsg.i 122 3} /* DATE RANGES MAY NOT OVERLAP */
 *                  undo setb, retry.
 *                end.
 *
 *                /* DETERMINE IF CURRENCIES ARE UNION. MEMBER, OR  */
 *                /* BASE CURR IN AFFECT AT THE END DATE            */
 *                {gprunp.i "mcpl" "p" "mc-chk-union-curr"
 *                          "(input curr1,
 *                            input exr_end_date,
 *                            output curr1-is-union)"}
 *
 *                {gprunp.i "mcpl" "p" "mc-chk-union-curr"
 *                          "(input curr2,
 *                            input exr_end_date,
 *                            output curr2-is-union)"}
 *
 *                {gprunp.i "mcpl" "p" "mc-chk-member-curr"
 *                          "(input curr1,
 *                            input exr_end_date,
 *                            output union-curr,
 *                            output curr1-is-member)"}
 *
 *                {gprunp.i "mcpl" "p" "mc-chk-member-curr"
 *                          "(input curr2,
 *                            input exr_end_date,
 *                            output union-curr,
 *                            output curr2-is-member)"}
 *
 *                /* ONE OF THE CURRENCIES MUST BE THE BASE */
 *                /* OR THE UNION CURRENCY                  */
 *                if not curr1-is-base and
 *                   not curr1-is-union and
 *                   not curr2-is-base and
 *                   not curr2-is-union then do:
 *                      {mfmsg.i 2666 3}
 *                    /* ONE CURRENCY MUST BE EITHER UNION OR BASE CURRENCY  */
 *                      next-prompt exr_end_date with frame b.
 *                      undo setb, retry.
 *                end.  /* NOT CURR1... */
 *
 *                /* IF ONE CURRENCY IS MEMBER CURRENCY, OTHER MUST BE UNION  */
 *                if (curr1-is-member and
 *                   not curr2-is-union) or
 *                   (curr2-is-member and
 *                   not curr1-is-union) then do:
 *                      {mfmsg.i 2664 3}
 *              /* MEMBER CURR CAN ONLY HAVE DIRECT EXCH RATE WITH UNION CURR */
 *                      next-prompt exr_end_date with frame b.
 *                      undo setb, retry.
 *                end.  /* IF (CURR1-IS-MEMBER...  */
 *
 *
 *                setrates: do on error undo, retry:
 *                   /* PROHIBIT INPUT IF UNION CURR AND MEMBER CURR */
 *                   prompt-for rate-amt1 when (not curr1-is-union
 *                                              or not curr2-is-member)
 *                              rate-amt2 when (not curr2-is-union
 *                                              or not curr1-is-member)
 *                   go-on (F5 CTRL-D).
 *
 *                   /* DO NOT ALLOW UNKNOWN VALUE ENTERED */
 *                   if input rate-amt1 = ? then do:
 *                      {mfmsg.i 1235 3} /* UNKNOWN VALUE NOT ALLOWED */
 *                      next-prompt rate-amt1 with frame b.
 *                      undo setrates, retry setrates.
 *                   end.
 *
 *                   if input rate-amt2 = ? then do:
 *                      {mfmsg.i 1235 3} /* UNKNOWN VALUE NOT ALLOWED */
 *                      next-prompt rate-amt2 with frame b.
 *                      undo setrates, retry setrates.
 *                   end.
 *
 *                   assign rate-amt1
 *                          rate-amt2.
 *
 *                   if lastkey = keycode("F5") or
 *                      lastkey = keycode("CTRL-D")
 *                      then do:
 *                      del-yn = yes.
 *                      {mfmsg01.i 11 1 del-yn} /*CONFIRM DELETE*/
 *                   end.
 *                   if del-yn then do:
 *                      /* ISSUE WARNING MESSAGE IF END DATE  */
 *                      /* < OR = TODAY                       */
 *                      if exr_end_date <= today then do:
 *                         del-yn = no.
 *                         {mfmsg01.i 2660 2 del-yn}
 *                         /* WARNING: DELETION COULD AFFECT      */
 *                         /* EXISTING TRANSACTIONS. CONTINUE?   */
 *                      end.    /* IF EXR_END_DATE <= TODAY.. */
 *
 *                      if del-yn then do:
 *                         delete exr_rate.
 *                         clear frame b.
 *                         assign recno = ?
 *                                del-yn = no.
 * /*L04F* *                  next loopb.  */
 * /*L04F*/                   leave innerloop.
 *
 *                      end.    /* IF DEL-YN... */
 *                   end.    /* IF DEL-YN... */
 *
 *
 *                   /* VALIDATE THE RATES THAT HAVE BEEN ENTERED */
 *                   /* ZERO OR NEGATIVE RATES ARE NOT ALLOWED */
 *                   if rate-amt1 <= 0 or rate-amt2 <= 0 then do:
 *                      {mfmsg.i 3163 3}
 *                      /* EXCHANGE RATE MUST BE > THAN ZERO */
 *                      if rate-amt1 = 0 then next-prompt rate-amt1.
 *                      else next-prompt rate-amt2.
 *                      undo setrates, retry.
 *                   end.   /* RATE-AMT1 = 0 OR RATE-AMT2 = 0... */
 *
 *                   assign exr_rate = if var-fld-match
 *                                     then rate-amt1 else rate-amt2
 *                          exr_rate2 = if var-fld-match
 *                                     then rate-amt2 else rate-amt1.
 *
 *
 *                   /* ISSUE WARNING MESSAGE IF END DATE  */
 *                   /* < OR = TODAY AND END DATE OR RATES */
 *                   /* HAVE CHANGED                       */
 *                   if (exr_end_date <= today and not new exr_rate and
 *                      (exr_end_date <> save-end-date or
 *                       rate-amt1 <> save-rate-amt1 or
 *                       rate-amt2 <> save-rate-amt2))
 *                   then do:
 *                      chg-ok = no.
 *                      {mfmsg01.i 2237 2 chg-ok}
 *                      /* WARNING: THIS CHANGE COULD AFFECT   */
 *                      /* EXISTING TRANSACTIONS. CONTINUE?    */
 *                      if not chg-ok then undo setb, retry.
 *                   end.    /* IF EXR_END_DATE <= TODAY..     */
 *
 *
 *                   /* ISSUE WARNING MESSAGE IF THIS IS A     */
 *                   /* EMU UNION/MEMBER EXCH RATE AND RATES   */
 *                   /* HAVE CHANGED                           */
 *                   if (is-EMU-exch-rate and not new exr_rate and
 *                       (rate-amt1 <> save-rate-amt1 or
 *                       rate-amt2 <> save-rate-amt2))
 *                   then do:
 *                      chg-ok = no.
 *                      {mfmsg01.i 2669 2 chg-ok}
 *                      /* WARNING: RATES CHANGED FOR EMU      */
 *                      /* EXCHANGE RATE. CONTINE?             */
 *                      if not chg-ok then undo setb, retry.
 *                   end.    /* IF IS-EMU-EXCH-RATE..          */
 *
 *                end.  /* END SETRATES BLOCK */
 *
 *             end.  /* END SETB BLOCK */
 *
 * /*L04F* *      FOLLOWING CODE MOVED BELOW...
 *           /* AUDIT TRAIL RECORDS WILL BE CREATED    */
 *           /* SHOWING ANY CHANGES THAT OCCURED       */
 *           {gpaud2.i &uniq_num1 = 1
 *                     &uniq_num2 = 2
 *                     &db_file   = exr_rate
 *                     &db_field  = exr_curr1
 *                     &db_field1 = exr_curr2}
 *L04F* *      END OF MOVED CODE    */
 *
 *          end.  /* END DATEFRAME BLOCK */
 *
 *          down 1.
 *          status input.
 *
 * /*L04F*/ *  leave innerloop.  /* PROCESS COMPLETED NORMALLY */
 * /*L04F*/ *end. /*innerloop*/
 *
 * /*L04F*/ /* AUDIT TRAIL RECORDS WILL BE CREATED    */
 * /*L04F*/ /* SHOWING ANY CHANGES THAT OCCURED       */
 * /*L04F*/ {gpaud2.i &uniq_num1 = 1
 *                  &uniq_num2 = 2
 *                  &db_file   = exr_rate
 *                  &db_field  = exr_curr1
 *                  &db_field1 = exr_curr2}
 *
 * /*L06X* * QUERIES NEED TO BE WRAPPED IN DO STATEMENT FOR GUI REQUIREMENTS */
 * /*L06X* * if var-fld-match then */
 * /*L06X*/ *if var-fld-match then do:
 *           open query q1 for each exr_rate no-lock
 *           where exr_curr1 = curr1
 *           and   exr_curr2 = curr2
 *           by exr_start_date.
 * /*L06X*/ *end.
 * /*L06X* * else     */
 * /*L06X*/ *else do:
 *          open query q1 for each exr_rate no-lock
 *          where exr_curr1 = curr2
 *          and   exr_curr2 = curr1
 *          by exr_start_date.
 * /*L06X*/ *end.
 *
 *        get last q1.
 *
 *        if available exr_rate then
 *           assign recno = ?
 *           next-start = exr_end_date + 1.
 *
 *       end.  * /*Loopb*/
 *
 *       clear frame b all.
 *       hide frame b.
 *
 *     end.  /* mainloop */
 *
 *     /* DELETE TEMPORARY FILES USED FOR AUDIT TRAIL */
 *     {gpaud3.i &uniq_num1 = 1
 *               &uniq_num2 = 2
 *               &db_file   = exr_rate
 *               &db_field  = exr_curr1}
 *
 *     status input.
 *
 *L09G*/
